import SyntaxHighlighter from '@/components/SyntaxHighlighter'
import { useEffect } from 'react'

const code1 = `
  const nums = [-1, 0, 1, 2, -1, -4]
`

const code2 = `
  const setFn = () => {
    const nums = [-1, 0, 1, 2, -1, -4]
    const result = []

    /**
     * 第一步：
     *    排序，使得后续可以通过指针跳跃快速排除重复元素，并为双指针法创造条件
     *    [-4, -1, -1, 0, 1, 2]
     */
    nums.sort((a, b) => a - b)
    /**
     * 第二步：
     *    外层循环固定第一个元素 a = nums[i];
     *    内层通过左右指针 left 和 right 分别 从 i + 1 和 数组末端向中间移动；
     *    因为至少需要三个数，所以 a 最大值 为 nums.length - 3。条件判断就是 < nums.length - 2
     */
    for(let i = 0; i < nums.length - 2; i++) {
      // 跳过重复的起始位置（注意 i > 0 的前置条件）
      if (i > 0 && nums[i] === nums[i - 1]) {
        continue
      }

      let left = i + 1 // 相当于 b
      let right = nums.length - 1 // 相当于 c
      const target = 0 - nums[i] // 如果 b + c = target，则说明满足条件

      // 如果 left >= right 则说明已遍历完 
      while(left < right) {
        const sum = nums[left] + nums[right] // 相当于 b + c

        if (target === sum) {
          result.push([nums[i], nums[left], nums[right]]) // 满足条件保存在 result 里

          // 跳过所有重复的左右指针元素；left + 1，right - 1
          while(left < right && nums[left] === nums[left + 1]) left++
          while(left < right && nums[right] === nums[right - 1]) right--

          // 保存后接着寻找
          left++
          right--
        } else if (sum < target) {
          // 值太小，需要往右边移动，增大数值
          left++
        } else {
          // 值太大，需要往左边移动，减小数值
          right--
        }
      }
    }

    console.log('result', result)
  }
`

function FindCondition() {
  const setFn = () => {
    const nums = [-1, 0, 1, 2, -1, -4]
    const result = []

    /**
     * 第一步：
     *    排序，使得后续可以通过指针跳跃快速排除重复元素，并为双指针法创造条件
     *    [-4, -1, -1, 0, 1, 2]
     */
    nums.sort((a, b) => a - b)
    /**
     * 第二步：
     *    外层循环固定第一个元素 a = nums[i];
     *    内层通过左右指针 left 和 right 分别 从 i + 1 和 数组末端向中间移动；
     *    因为至少需要三个数，所以 a 最大值 为 nums.length - 3。条件判断就是 < nums.length - 2
     */
    for(let i = 0; i < nums.length - 2; i++) {
      // 跳过重复的起始位置（注意 i > 0 的前置条件）
      if (i > 0 && nums[i] === nums[i - 1]) {
        continue
      }

      let left = i + 1 // 相当于 b
      let right = nums.length - 1 // 相当于 c
      const target = 0 - nums[i] // 如果 b + c = target，则说明满足条件

      // 如果 left >= right 则说明已遍历完 
      while(left < right) {
        const sum = nums[left] + nums[right] // 相当于 b + c

        if (target === sum) {
          result.push([nums[i], nums[left], nums[right]]) // 满足条件保存在 result 里

          // 跳过所有重复的左右指针元素；left + 1，right - 1
          while(left < right && nums[left] === nums[left + 1]) left++
          while(left < right && nums[right] === nums[right - 1]) right--

          // 保存后接着寻找
          left++
          right--
        } else if (sum < target) {
          // 值太小，需要往右边移动，增大数值
          left++
        } else {
          // 值太大，需要往左边移动，减小数值
          right--
        }
      }
    }

    console.log('result', result)
  }

  useEffect(() => {
    setFn()
  }, [])

  return (
    <div>
      <p>给你一个包含n个整数的数组 nums，判断 nums 中是否存在三个元素 a,b,c 使得 a + b + c = 0。找出所有满足条件且不重复的三元组</p>
      <SyntaxHighlighter children={code1} />
      <p>代码逻辑：</p>
      <SyntaxHighlighter children={code2} />
    </div>
  )
}

export default FindCondition